package org.lee.mq.config;

import org.lee.mq.util.StringUtil;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * @author jackielee
 * @version 1.0
 * @description TopicRabbitConfig
 * @date 2021/7/5
 **/
@Configuration
public class TopicRabbitConfig {

    @Bean("#{queueNames." + RabbitMqConstants.QUEUE_NAME_SHORT_PAY + "}")
    public Queue topicPayQueue() {
        return new Queue(queueName(RabbitMqConstants.ORDER_PAY_NOTIFY_QUEUE_NAME), true);
    }

    @Bean("#{queueNames." + RabbitMqConstants.QUEUE_NAME_SHORT_PAY_FINISH + "}")
    public Queue topicPayFinishQueue() {
        return new Queue(queueName(RabbitMqConstants.ORDER_PAY_FINISH_NOTIFY_QUEUE_NAME), true);
    }

    @Bean("#{queueNames." + RabbitMqConstants.QUEUE_NAME_SHORT_REFUND + "}")
    public Queue topicRefundQueue() {
        return new Queue(queueName(RabbitMqConstants.ORDER_REFUND_NOTIFY_QUEUE_NAME), true);
    }

    @Bean("#{queueNames." + RabbitMqConstants.QUEUE_NAME_SHORT_REFUND_FINISH + "}")
    public Queue topicRefundFinishQueue() {
        return new Queue(queueName(RabbitMqConstants.ORDER_REFUND_FINISH_NOTIFY_QUEUE_NAME), true);
    }

    @Bean(RabbitMqConstants.ORDER_PAY_NOTIFY_EXCHANGE_NAME)
    public TopicExchange topicPayExchange() {
        return new TopicExchange(RabbitMqConstants.ORDER_PAY_NOTIFY_EXCHANGE_NAME, true, false);
    }

    @Bean(RabbitMqConstants.ORDER_REFUND_NOTIFY_EXCHANGE_NAME)
    public TopicExchange topicRefundExchange() {
        return new TopicExchange(RabbitMqConstants.ORDER_REFUND_NOTIFY_EXCHANGE_NAME, true, false);
    }

    @Bean
    Binding bindingPayTopic(@Qualifier("#{queueNames." + RabbitMqConstants.QUEUE_NAME_SHORT_PAY + "}") Queue queue,
                            @Qualifier(RabbitMqConstants.ORDER_PAY_NOTIFY_EXCHANGE_NAME) TopicExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(RabbitMqConstants.ORDER_ROUTE_KEY_ALL);
    }

    @Bean
    Binding bindingPayFinishTopic(@Qualifier("#{queueNames." + RabbitMqConstants.QUEUE_NAME_SHORT_PAY_FINISH + "}") Queue queue,
                                  @Qualifier(RabbitMqConstants.ORDER_PAY_NOTIFY_EXCHANGE_NAME) TopicExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(RabbitMqConstants.ORDER_ROUTE_KEY_ALL);
    }

    @Bean
    Binding bindingRefundTopic(@Qualifier("#{queueNames." + RabbitMqConstants.QUEUE_NAME_SHORT_REFUND + "}") Queue queue,
                               @Qualifier(RabbitMqConstants.ORDER_REFUND_NOTIFY_EXCHANGE_NAME) TopicExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(RabbitMqConstants.ORDER_ROUTE_KEY_ALL);
    }

    @Bean
    Binding bindingRefundFinishTopic(@Qualifier("#{queueNames." + RabbitMqConstants.QUEUE_NAME_SHORT_REFUND_FINISH + "}") Queue queue,
                                     @Qualifier(RabbitMqConstants.ORDER_REFUND_NOTIFY_EXCHANGE_NAME) TopicExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(RabbitMqConstants.ORDER_ROUTE_KEY_ALL);
    }

//    @Bean
//    public RabbitTemplate rabbitTemplate(CachingConnectionFactory connectionFactory) {
//        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
//        rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
//        return rabbitTemplate;
//    }


    @Value("${spring.application.name}")
    private String appName;

    private String queueName(String name) {
        return StringUtil.format("{}.{}", appName, name);
    }

    @Bean("queueNames")
    Map<String, String> queueNames() {
        Map<String, String> names = new HashMap<>();
        names.put(RabbitMqConstants.QUEUE_NAME_SHORT_PAY, queueName(RabbitMqConstants.ORDER_PAY_NOTIFY_QUEUE_NAME));
        names.put(RabbitMqConstants.QUEUE_NAME_SHORT_PAY_FINISH, queueName(RabbitMqConstants.ORDER_PAY_FINISH_NOTIFY_ROUTE_KEY));
        names.put(RabbitMqConstants.QUEUE_NAME_SHORT_REFUND, queueName(RabbitMqConstants.ORDER_REFUND_NOTIFY_QUEUE_NAME));
        names.put(RabbitMqConstants.QUEUE_NAME_SHORT_REFUND_FINISH, queueName(RabbitMqConstants.ORDER_REFUND_FINISH_NOTIFY_QUEUE_NAME));
        return names;
    }
}
